package org.nobject.common.db.member;

import org.nobject.common.lang.ObjectUtils;
import org.nobject.common.lang.StringUtils;

/**
 * SQL条件元素
 *
 * @author bianrongjun
 * @version 1.0
 */
public class SqlWE{
	
	/** 关系 */
	public static enum Relate{
		/** 并且 */
		AND,
		/** 或 */
		OR
	}
	
	/** 类型 */
	public static enum Type{
		/** 字符串 */
		STR, 
		/** 数字 */
		NUM,
		/** 日期 */
		DATE
	}
	
	/** 比较符 */
	public static enum Compare{
		 /** 相似 */
		like,
		/** 相等 */
		equal,
		/** 不等 */
		notEqual,
		/** 左相似 */
		leftLike,
		/** 右相似 */
		rightLike,
		/** 不相似 */
		notEquals,
		/** 小于 */
		less,
		/** 小于等于 */
		lessOrEqual,
		/** 大于 */
		more,
		/** 大于等于 */
		moreOrEqual,
		/** 在之中 */
		in,
		/** 不相似 */
		notLike,
		/** 不在之中 */
		notIn,
		/** NULL */
		nvll,
		/** 不为NULL */
		notNull
	}
	
	public final static class Separate{
		public final static String space=" ";
		public final static String comma=",";
	}
	
	/** 表前缀 */
	public String pre;
	/** 字段名 */
	public String column;
	/** 比较符 */
	public Compare cmp;
	/** 关系符 */
	public Relate relate;
	/** 类型 */
	public Type type;
	/** 值 */
	public Object value;
	/** 分隔符（当一个值使用分割方式传入时） */
	public String separate;
	
	/**
	 * 构造函数 
	 * @param pre
	 * @param column
	 * @param cmp
	 * @param relate
	 * @param type
	 * @param value
	 */
	public SqlWE(String pre, String column, Compare cmp, Relate relate, Type type, Object value,String separate) {
		this.pre 		= pre;
		this.column 	= column;
		this.cmp 		= cmp;
		this.relate 	= relate;
		this.type 		= type;
		this.value 		= value;
		this.separate	=separate;
	}

	/**
	 * 构造函数 
	 * @param pre
	 * @param column
	 * @param cmp
	 * @param relate
	 * @param value
	 * @param type
	 */
	public SqlWE(String pre,String column, Compare cmp, Relate relate, Type type) {
		this(pre, column, cmp, relate, type, null,null);
	}
	
	/**
	 * 构造函数 
	 * @param column
	 * @param cmp
	 * @param relate
	 * @param type
	 * @param separate
	 */
	public SqlWE(String column, Compare cmp, Relate relate, Type type,String separate) {
		this(null, column, cmp, relate, type, null,separate);
	}
	
	/**
	 * 构造函数 
	 * @param column
	 * @param cmp
	 * @param relate
	 * @param value
	 */
	public SqlWE(String column, Compare cmp, Relate relate, Object value) {
		this(null, column, cmp, relate, null, value,null);
	}
	
	/**
	 * 构造函数 
	 * @param column
	 * @param cmp
	 * @param relate
	 * @param value
	 */
	public SqlWE(String column, Compare cmp, Object value) {
		this(null, column, cmp, null, null, value,null);
	}
	
	/**
	 * 构造函数 
	 * @param column
	 * @param cmp
	 * @param relate
	 * @param type
	 */
	public SqlWE(String column, Compare cmp, Relate relate, Type type) {
		this(null, column, cmp, relate, type, null,null);
	}
	
	
	
	/** 
	 * 获取SQL
	 * @param preTab 前缀
	 */
	public String getSql(String preTab){
		this.pre=preTab;
		return this.getSql();
	}
	
	/** 比较符号 */
	private static Compare[] _cmps=new Compare[]{
		Compare.equal,
		Compare.notEqual,
		Compare.less,
		Compare.lessOrEqual,
		Compare.more,
		Compare.moreOrEqual 
	};
	
	/** 
	 * 获取SQL
	 */
	public String getSql(){
		if(this.separate!=null) return getSeparateSql();
		return _getSql(value);
	}
	
	/** 
	 * getSeparateSql
	 */
	public String getSeparateSql(){
		String[] vs=((String)this.value).split(this.separate);
		String sql=" "+relate+" (";
		for (int i = 0; i < vs.length; i++) {
			if(i>0) sql+=" OR ";
			sql+=_getSql(vs[i].trim());
		}
		sql+=")";
		return sql;
	}
	
	/** 
	 * _getSql
	 * @param value
	 */
	public String _getSql(Object value){
		String sql=(StringUtils.isEmpty(pre)?"":pre+".")+column;
		if(ObjectUtils.in(cmp,_cmps)){
			if(value==null) throw new RuntimeException("不支持目标值为null."+column);
			String v= value instanceof String? "'"+(String)value+"'":StringUtils.toString0(value);
			if(cmp.equals(Compare.equal)) 				sql+=" = "+v;
			else if(cmp.equals(Compare.notEqual)) 		sql+=" != "+v;
			else if(cmp.equals(Compare.less)) 			sql+=" < "+v;
			else if(cmp.equals(Compare.lessOrEqual)) 	sql+=" <= "+v;
			else if(cmp.equals(Compare.more)) 			sql+=" > "+v;
			else if(cmp.equals(Compare.moreOrEqual)) 	sql+=" >= "+v;
		}
		else if(cmp.equals(Compare.like))			sql+=" LIKE '%"		+value+"%'";
		else if(cmp.equals(Compare.leftLike))		sql+=" LIKE '"		+value+"%'";
		else if(cmp.equals(Compare.rightLike))		sql+=" LIKE '%"		+value+"'";
		else if(cmp.equals(Compare.notLike))		sql+=" NOT LIKE '%"	+value+"%'";
		else if(cmp.equals(Compare.in))				sql+=" IN ("		+value+")";
		else if(cmp.equals(Compare.notIn))			sql+=" NOT IN ("	+value+")";
		else if(cmp.equals(Compare.nvll))			sql+=" IS NULL";
		else if(cmp.equals(Compare.notNull))		sql+=" IS NOT NULL";
		return sql;
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#clone()
	 */
	public SqlWE clone(){
		return new SqlWE(pre, column,cmp,relate,type,value,separate);
	}
}
